package com.example.glgk.service.indicatorReport;

import com.example.glgk.dto.indicator.IndicatorCalculateDto;
import com.example.glgk.dto.indicatorReport.*;
import com.example.glgk.entity.DepartmentIndicatorEntity;
import com.example.glgk.entity.ElementDataEntity;
import com.example.glgk.entity.IndicatorDataEntity;
import com.example.glgk.mapper.ElementDataMapper;
import com.example.glgk.mapper.indicatorReport.IndicatorReportMapper;
import com.example.glgk.service.gather.GatherCommonService;
import com.example.glgk.utils.Calculator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.Year;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 指标报告service
 */
@Service
@Slf4j
public class IndicatorReportService {

    @Autowired
    IndicatorReportMapper indicatorReportMapper;

    @Autowired
    ElementDataMapper elementDataMapper;


    public IndicatorExplainVO getIndicatorExplain(IndicatorReportDto indicatorReportDto) {
        return indicatorReportMapper.getIndicatorExplain(indicatorReportDto);
    }


    public IndicatorOverAllSituationVO getIndicatorOverAllSituation(IndicatorReportDto indicatorReportDto) {

        IndicatorOverAllSituationVO indicatorOverAllSituationVO = new IndicatorOverAllSituationVO();
        //1.根据指标序号先查出指标相关信息，比如计算公式等
        IndicatorDataEntity indicatorDataEntity = indicatorReportMapper.getIndicatorByXh(indicatorReportDto);

        //设置近6年的年份，因为涉及到第5年的同比计算，所以要往前查6年
        List<String> yearList = getLastSixYears();
        indicatorReportDto.setYearList(yearList);

        indicatorOverAllSituationVO.setCurYear(indicatorReportDto.getYearList().get(0));
        indicatorOverAllSituationVO.setIndicatorName(indicatorDataEntity.getIndexName());

        //2.取出计算公式涉及到的元素id并去重
        //todo  先不考虑特殊情况：部分指标没有计算公式
        String[] split = indicatorDataEntity.getIds().split(",");
        List<String> elementIds = new ArrayList<>();
        elementIds.addAll(Arrays.asList(split));
        elementIds = elementIds.stream().distinct().collect(Collectors.toList());

        //3.查询元素定义表，确定元素来源：天表 月表 手填表
        List<ElementDataEntity> elementDataEntities = elementDataMapper.query(elementIds);
        //分别得出天表，月表，手填表的元素数据
        List<ElementDataEntity> dayTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "1".equals(s.getDataTable())).collect(Collectors.toList());
        List<ElementDataEntity> monthTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "2".equals(s.getDataTable())).collect(Collectors.toList());
        List<ElementDataEntity> handTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "3".equals(s.getDataTable())).collect(Collectors.toList());

        //4.查出近五年的指标数据
        //存放近五年的天表 月表 手填表数据
        List<DepartmentIndicatorEntity> indicatorOverPastYearsList = new ArrayList<>();// 存放当前时间的所有的天表、月表、手填表数据


        //查出天表近几年数据
        if (!CollectionUtils.isEmpty(dayTable)) {
            indicatorReportDto.setElementIds(dayTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            List<DepartmentIndicatorEntity> dayData = indicatorReportMapper.queryDayDataByYears(indicatorReportDto);
            indicatorOverPastYearsList.addAll(dayData);
        }

        //查出月表近几年数据
        if (!CollectionUtils.isEmpty(monthTable)) {
            indicatorReportDto.setElementIds(monthTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            List<DepartmentIndicatorEntity> monthData = indicatorReportMapper.queryMonthDataByYears(indicatorReportDto);
            indicatorOverPastYearsList.addAll(monthData);
        }

        // 查出手填表近几年数据
/*        if (!CollectionUtils.isEmpty(handTable)) {
            indicatorReportDto.setElementIds(handTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            List<String> taskIds = indicatorReportMapper.selectReportTasks(indicatorReportDto);
            if (taskIds.size() > 0) {
                indicatorReportDto.setTaskIds(taskIds);
                List<DepartmentIndicatorEntity> handData = indicatorReportMapper.queryHandDataByYears(indicatorReportDto);
                indicatorOverPastYearsList.addAll(handData);
            }
        }*/


        //查今年12个月
        indicatorReportDto.setCurYear(indicatorReportDto.getYearList().get(0));
        if (!CollectionUtils.isEmpty(dayTable)) {
            indicatorReportDto.setElementIds(dayTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            List<DepartmentIndicatorEntity> dayData = indicatorReportMapper.queryDayDataByMonths(indicatorReportDto);
            indicatorOverPastYearsList.addAll(dayData);
        }

        //查今年12个月
        if (!CollectionUtils.isEmpty(monthTable)) {
            indicatorReportDto.setElementIds(monthTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            List<DepartmentIndicatorEntity> monthData = indicatorReportMapper.queryMonthDataByMonths(indicatorReportDto);
            indicatorOverPastYearsList.addAll(monthData);
        }

        //查今年12个月
        if (!CollectionUtils.isEmpty(handTable)) {
            indicatorReportDto.setElementIds(handTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            List<String> taskIds = indicatorReportMapper.selectReportTasksByMonths(indicatorReportDto);
            if (taskIds.size() > 0) {
                indicatorReportDto.setTaskIds(taskIds);
                List<DepartmentIndicatorEntity> handData = indicatorReportMapper.queryHandDataByMonths(indicatorReportDto);
                indicatorOverPastYearsList.addAll(handData);
            }
        }


        //取出分子、分母的计算公式
        String formulaId = indicatorDataEntity.getCalculationFormulaId();
        String[] item = formulaId.split("/");
        String fzFormula = item[0];
        String fmFormula = item[1];

        //3.计算分子值 分母值 指标值  同比值  满分值增幅暂时不知道什么意思 先不计算

        Map<String, String> currentMapValue = new HashMap<>();
        Map<String, String> lastMapValue = new HashMap<>();
        Map<String, String> beforeMapValue = new HashMap<>();
        Map<String, String> previousMapValue = new HashMap<>();
        Map<String, String> endMapValue = new HashMap<>();
        Map<String, String> finalMapValue = new HashMap<>();

        currentMapValue = indicatorOverPastYearsList.stream().filter(e -> e.getTime().equals(indicatorReportDto.getYearList().get(0))).collect(Collectors.toMap(e -> "${" + e.getId() + "}", e -> e.getElementNumber()));
        lastMapValue = indicatorOverPastYearsList.stream().filter(e -> e.getTime().equals(indicatorReportDto.getYearList().get(1))).collect(Collectors.toMap(e -> "${" + e.getId() + "}", e -> e.getElementNumber()));
        beforeMapValue = indicatorOverPastYearsList.stream().filter(e -> e.getTime().equals(indicatorReportDto.getYearList().get(2))).collect(Collectors.toMap(e -> "${" + e.getId() + "}", e -> e.getElementNumber()));
        previousMapValue = indicatorOverPastYearsList.stream().filter(e -> e.getTime().equals(indicatorReportDto.getYearList().get(3))).collect(Collectors.toMap(e -> "${" + e.getId() + "}", e -> e.getElementNumber()));
        endMapValue = indicatorOverPastYearsList.stream().filter(e -> e.getTime().equals(indicatorReportDto.getYearList().get(4))).collect(Collectors.toMap(e -> "${" + e.getId() + "}", e -> e.getElementNumber()));
        finalMapValue = indicatorOverPastYearsList.stream().filter(e -> e.getTime().equals(indicatorReportDto.getYearList().get(5))).collect(Collectors.toMap(e -> "${" + e.getId() + "}", e -> e.getElementNumber()));


        //近五年分子值
        String numerator = "0";
        String lastNumerator = "0";
        String beforeNumerator = "0";
        String previousNumerator = "0";
        String endNumerator = "0";

        numerator = Calculator.conversionToSting(fzFormula, currentMapValue);
        lastNumerator = Calculator.conversionToSting(fzFormula, lastMapValue);
        beforeNumerator = Calculator.conversionToSting(fzFormula, beforeMapValue);
        previousNumerator = Calculator.conversionToSting(fzFormula, previousMapValue);
        endNumerator = Calculator.conversionToSting(fzFormula, endMapValue);


        //近五年分母值
        String denominator = "0";
        String lastDenominator = "0";
        String beforeDenominator = "0";
        String previousDenominator = "0";
        String endDenominator = "0";

        denominator = Calculator.conversionToSting(fmFormula, currentMapValue);
        lastDenominator = Calculator.conversionToSting(fmFormula, lastMapValue);
        beforeDenominator = Calculator.conversionToSting(fmFormula, beforeMapValue);
        previousDenominator = Calculator.conversionToSting(fmFormula, previousMapValue);
        endDenominator = Calculator.conversionToSting(fmFormula, endMapValue);


        //近五年指标值
        String curYearValue = "0";
        String lastYearValue = "0";
        String beforeYearValue = "0";
        String previousYearValue = "0";
        String endYearValue = "0";
        String finalYearValue = "0";

        curYearValue = Calculator.conversionToSting(formulaId, currentMapValue);//当前指标值,如果当前指标涉及到多个元素计算，那么结果就是多元素数据计算的值，如果不涉及，就是其本身的值
        lastYearValue = Calculator.conversionToSting(formulaId, lastMapValue);//当前指标值,如果当前指标涉及到多个元素计算，那么结果就是多元素数据计算的值，如果不涉及，就是其本身的值
        beforeYearValue = Calculator.conversionToSting(formulaId, beforeMapValue);//当前指标值,如果当前指标涉及到多个元素计算，那么结果就是多元素数据计算的值，如果不涉及，就是其本身的值
        previousYearValue = Calculator.conversionToSting(formulaId, previousMapValue);//当前指标值,如果当前指标涉及到多个元素计算，那么结果就是多元素数据计算的值，如果不涉及，就是其本身的值
        endYearValue = Calculator.conversionToSting(formulaId, endMapValue);//当前指标值,如果当前指标涉及到多个元素计算，那么结果就是多元素数据计算的值，如果不涉及，就是其本身的值
        finalYearValue = Calculator.conversionToSting(formulaId, finalMapValue);//当前指标值,如果当前指标涉及到多个元素计算，那么结果就是多元素数据计算的值，如果不涉及，就是其本身的值

        indicatorOverAllSituationVO.setIndicatorValue(curYearValue);

        String dx = indicatorDataEntity.getDx();

        if ("0".equals(dx) || "1".equals(dx)) {
            //上升指标，按照降序进行排序
            BigDecimal curYearBdValue = new BigDecimal(curYearValue.equals("-") ? "0" : curYearValue);
            BigDecimal lastYearBdValue = new BigDecimal(lastYearValue.equals("-") ? "0" : lastYearValue);
            if (curYearBdValue.compareTo(lastYearBdValue) > 0) {
                indicatorOverAllSituationVO.setIndicatorYearTrend("上升");
            } else if (curYearBdValue.compareTo(lastYearBdValue) == 0) {
                indicatorOverAllSituationVO.setIndicatorYearTrend("持平");
            } else {
                indicatorOverAllSituationVO.setIndicatorYearTrend("下降");
            }
        } else {
            //下降指标，按照升序进行排序
            BigDecimal curYearBdValue = new BigDecimal(curYearValue.equals("-") ? "0" : curYearValue);
            BigDecimal lastYearBdValue = new BigDecimal(lastYearValue.equals("-") ? "0" : lastYearValue);
            if (curYearBdValue.compareTo(lastYearBdValue) < 0) {
                indicatorOverAllSituationVO.setIndicatorYearTrend("上升");
            } else if (curYearBdValue.compareTo(lastYearBdValue) == 0) {
                indicatorOverAllSituationVO.setIndicatorYearTrend("持平");
            } else {
                indicatorOverAllSituationVO.setIndicatorYearTrend("下降");
            }
        }


        double mfz = indicatorDataEntity.getMfz();

        IndicatorOverYearsVO curIndicatorVO = new IndicatorOverYearsVO();
        curIndicatorVO.setYearTime(indicatorReportDto.getYearList().get(0));//年度
        curIndicatorVO.setNumerator(numerator);//分子
        curIndicatorVO.setDenominator(denominator);//分母
        curIndicatorVO.setIndicatorValue(curYearValue);//指标值
        curIndicatorVO.setGKValue("-");//国考数据
        curIndicatorVO.setFullValue(String.valueOf(mfz));//满分值
        curIndicatorVO.setFullValueAmplification("-");//满分值增幅
        curIndicatorVO.setYoyValue(calculateGrowthRate(curYearValue, lastYearValue));//同比

        IndicatorOverYearsVO lastIndicatorVO = new IndicatorOverYearsVO();
        lastIndicatorVO.setYearTime(indicatorReportDto.getYearList().get(1));//年度
        lastIndicatorVO.setNumerator(lastNumerator);//分子
        lastIndicatorVO.setDenominator(lastDenominator);//分母
        lastIndicatorVO.setIndicatorValue(lastYearValue);//指标值
        lastIndicatorVO.setGKValue("-");//国考数据
        lastIndicatorVO.setFullValue(String.valueOf(mfz));//满分值
        lastIndicatorVO.setFullValueAmplification("-");//满分值增幅
        lastIndicatorVO.setYoyValue(calculateGrowthRate(lastYearValue, beforeYearValue));//同比

        IndicatorOverYearsVO beforeIndicatorVO = new IndicatorOverYearsVO();
        beforeIndicatorVO.setYearTime(indicatorReportDto.getYearList().get(2));//年度
        beforeIndicatorVO.setNumerator(beforeNumerator);//分子
        beforeIndicatorVO.setDenominator(beforeDenominator);//分母
        beforeIndicatorVO.setIndicatorValue(beforeYearValue);//指标值
        beforeIndicatorVO.setGKValue("-");//国考数据
        beforeIndicatorVO.setFullValue(String.valueOf(mfz));//满分值
        beforeIndicatorVO.setFullValueAmplification("-");//满分值增幅
        beforeIndicatorVO.setYoyValue(calculateGrowthRate(beforeYearValue, previousYearValue));//同比

        IndicatorOverYearsVO previousIndicatorVO = new IndicatorOverYearsVO();
        previousIndicatorVO.setYearTime(indicatorReportDto.getYearList().get(3));//年度
        previousIndicatorVO.setNumerator(previousNumerator);//分子
        previousIndicatorVO.setDenominator(previousDenominator);//分母
        previousIndicatorVO.setIndicatorValue(previousYearValue);//指标值
        previousIndicatorVO.setGKValue("-");//国考数据
        previousIndicatorVO.setFullValue(String.valueOf(mfz));//满分值
        previousIndicatorVO.setFullValueAmplification("-");//满分值增幅
        previousIndicatorVO.setYoyValue(calculateGrowthRate(previousYearValue, endYearValue));//同比

        IndicatorOverYearsVO endIndicatorVO = new IndicatorOverYearsVO();
        endIndicatorVO.setYearTime(indicatorReportDto.getYearList().get(4));//年度
        endIndicatorVO.setNumerator(endNumerator);//分子
        endIndicatorVO.setDenominator(endDenominator);//分母
        endIndicatorVO.setIndicatorValue(endYearValue);//指标值
        endIndicatorVO.setGKValue("-");//国考数据
        endIndicatorVO.setFullValue(String.valueOf(mfz));//满分值
        endIndicatorVO.setFullValueAmplification("-");//满分值增幅
        endIndicatorVO.setYoyValue(calculateGrowthRate(endYearValue, finalYearValue));//同比

        indicatorOverAllSituationVO.getIndicatorOverYearsVOList().add(curIndicatorVO);
        indicatorOverAllSituationVO.getIndicatorOverYearsVOList().add(lastIndicatorVO);
        indicatorOverAllSituationVO.getIndicatorOverYearsVOList().add(beforeIndicatorVO);
        indicatorOverAllSituationVO.getIndicatorOverYearsVOList().add(previousIndicatorVO);
        indicatorOverAllSituationVO.getIndicatorOverYearsVOList().add(endIndicatorVO);


        return indicatorOverAllSituationVO;
    }


    public List<IndicatorOverMonthsVO> getIndicatorMonthByYear(IndicatorReportDto indicatorReportDto) {

        List<IndicatorOverMonthsVO> resultList = new ArrayList<>();
        //1.根据指标序号先查出指标相关信息，比如计算公式等
        IndicatorDataEntity indicatorDataEntity = indicatorReportMapper.getIndicatorByXh(indicatorReportDto);

        //2.取出计算公式涉及到的元素id并去重
        //todo  先不考虑特殊情况：部分指标没有计算公式
        String[] split = indicatorDataEntity.getIds().split(",");
        List<String> elementIds = new ArrayList<>();
        elementIds.addAll(Arrays.asList(split));
        elementIds = elementIds.stream().distinct().collect(Collectors.toList());

        //3.查询元素定义表，确定元素来源：天表 月表 手填表
        List<ElementDataEntity> elementDataEntities = elementDataMapper.query(elementIds);
        //分别得出天表，月表，手填表的元素数据
        List<ElementDataEntity> dayTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "1".equals(s.getDataTable())).collect(Collectors.toList());
        List<ElementDataEntity> monthTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "2".equals(s.getDataTable())).collect(Collectors.toList());
        List<ElementDataEntity> handTable = elementDataEntities.stream().filter(s -> StringUtils.isNotBlank(s.getDataTable()) && "3".equals(s.getDataTable())).collect(Collectors.toList());

        List<DepartmentIndicatorEntity> monthData = new ArrayList<DepartmentIndicatorEntity>();
        //查今年12个月
        if (!CollectionUtils.isEmpty(dayTable)) {
            indicatorReportDto.setElementIds(dayTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            monthData.addAll(indicatorReportMapper.queryDayDataByMonths(indicatorReportDto));

        }

        //查今年12个月
        if (!CollectionUtils.isEmpty(monthTable)) {
            indicatorReportDto.setElementIds(monthTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            monthData.addAll(indicatorReportMapper.queryMonthDataByMonths(indicatorReportDto));

        }

        //查今年12个月
        if (!CollectionUtils.isEmpty(handTable)) {
            indicatorReportDto.setElementIds(handTable.stream().map(ElementDataEntity::getId).collect(Collectors.toList()));
            List<String> taskIds = indicatorReportMapper.selectReportTasksByMonths(indicatorReportDto);
            if (taskIds.size() > 0) {
                indicatorReportDto.setTaskIds(taskIds);
                monthData.addAll(indicatorReportMapper.queryHandDataByMonths(indicatorReportDto));
            }
        }
        //使用monthData 计算每个月指标的值
        List<String> monthByYear = getMonthByYear(indicatorReportDto.getCurYear());
        for (String month : monthByYear) {
            Map<String, String> itemMap = monthData.stream().filter(e -> e.getTime().equals(month)).collect(Collectors.toMap(e -> "${" + e.getId() + "}", e -> e.getElementNumber()));
            for (String elementId : elementIds) {
                String elementNumber = itemMap.get(elementId);
                if (StringUtils.isBlank(elementNumber)){
                    itemMap.put(elementId, "0");
                }
            }
            String indexNumber = Calculator.conversionToSting(indicatorDataEntity.getCalculationFormulaId(), itemMap);
            if ("-".equals(indexNumber)){
                indexNumber = "0";
            }
            IndicatorOverMonthsVO indicatorOverMonthsVO = new IndicatorOverMonthsVO();
            indicatorOverMonthsVO.setIndicatorValue(indexNumber);
            indicatorOverMonthsVO.setMonthTime(month);
            resultList.add(indicatorOverMonthsVO);
        }
        //取出分子、分母的计算公式
        return resultList;
    }

    private static List<String> getMonthByYear(String year) {
        ArrayList<String> monthList = new ArrayList<>();
        for (int i =1; i <=12; i++) {
            monthList.add(year + "-" + String.format("%02d", i));
        }
        return monthList;
    }

    public static void main(String[] args) {
        List<String> monthByYear = getMonthByYear("2024");
        System.out.println(monthByYear);
    }

    /**
     * 获取近6年的年份
     */
    private List<String> getLastSixYears() {
        List<String> fiveYearsList = new ArrayList<>();
        Year year = Year.now();
        fiveYearsList.add(year.toString());
        fiveYearsList.add(year.minusYears(1).toString());
        fiveYearsList.add(year.minusYears(2).toString());
        fiveYearsList.add(year.minusYears(3).toString());
        fiveYearsList.add(year.minusYears(4).toString());
        fiveYearsList.add(year.minusYears(5).toString());
        return fiveYearsList;
    }

    public String calculateGrowthRate(String currentValue, String previousValue) {
        if (currentValue.equals("-") || previousValue.equals("-")) {
            return "-"; // 当值为 "-" 时，无法计算增长率，直接返回 "-"
        }

        double current = Double.parseDouble(currentValue);
        double previous = Double.parseDouble(previousValue);

        if (previous == 0.0) {
            return "0"; // 当前值为非零而上一期值为零时,直接返回0，无意义
        }

        double growthRate = (current - previous) / previous;
        return String.format("%.2f", growthRate); // 将增长率转换为字符串，并返回,保留两位小数，四舍五入
    }

    public void getIndicatorRiskOverAllSituation(IndicatorReportDto indicatorReportDto) {
    }

    public void getIndicatorStandard(IndicatorReportDto indicatorReportDto) {

    }
}
